import os
import requests
import shutil
import concurrent.futures  
import time
import json
from datetime import datetime, timedelta
from PIL import Image
from io import BytesIO
from Login import login
from rebot import rebotSendMessage
# 机器人发消息 关闭时直接输出
rebotMode=1

headers = {
   'Cookie': '',
   'Host': 'perfeye.console.testplus.cn'
}
# 获取今天的日期
today=datetime.today().strftime('%Y-%m-%d')
# 获取昨天的日期
yesterday = (datetime.today() - timedelta(days=1)).strftime('%Y-%m-%d')
# 获取七天前的日期
seven_days_ago = (datetime.today() - timedelta(days=7)).strftime('%Y-%m-%d')
total_url = f"https://automation-api.testplus.cn/api/pipeline/304/performance/trend?pipelineId=304&startTime={seven_days_ago}+00:00:00&endTime={yesterday}+23:59:59&projectId=yycs"
deviceName_to_find = "(YYCS)"  
scenes=['惠安镇','辽东郡','秀水郡']
deviceNames=['园区-GPU-2070','园区-GPU-1060','园区-GPU-1050ti']
default_message=f"\n\n## 月影传说{today}场景性能情况汇总\n\n"
message=f"\n\n## 月影传说{today}场景性能情况汇总\n\n"
newPerfeyeUrlList=[]
lowPerfeyeUrlList=[]
# 最优案例
max_case={}

def parse_duration(duration_str):
    # 分割字符串，获取天数、小时数、分钟数和秒数
    parts = duration_str.split()
    assert len(parts) == 1, "Expected a single duration string"
    duration_details = parts[0].replace('"', '').split(' ')  # 去除可能的引号并分割细节
    # 将字符串转换为整数，并计算总秒数
    days, hours, minutes, seconds = (int(detail.strip('dhms')) for detail in duration_details)
    total_seconds = days * 86400 + hours * 3600 + minutes * 60 + seconds
    return total_seconds
def getIndicator_diction(data,mode='dateList'):
    indicator_data = {}  
    if 'data' not in data:
        print('请求失败')
        return False
    for item in data['data']:
        case_name = item['caseName']  
        if case_name not in scenes:
            continue
        device_name = item['deviceName']  
        # 使用find()方法找到子字符串的位置  只保留简单的设备名
        position = device_name.find(deviceName_to_find)  
        if position != -1:  
            device_name = device_name[:position]  
        create_time = item['createTime']  
        tp90 = item['LabelFPS.TP90']  
        jank = item['LabelFPS.Jank(/10min)']  
        peak_memory = item['LabelMemory.PeakMemory(MB)']  
        perfeye = item['perfeye']  
        if case_name not in indicator_data:  
            indicator_data[case_name] = {}  
        if mode=='dateList':
            if device_name not in indicator_data[case_name]:  
                indicator_data[case_name][device_name] = []   
            indicator_data[case_name][device_name].append({  
                'date': create_time,
                'tp90': round(float(tp90),2),  
                'jank': round(float(jank),2),  
                'memory': round(float(peak_memory),2),  
                'perfeye': perfeye  
            })
        else:
            if device_name not in indicator_data[case_name]:  
                indicator_data[case_name][device_name] = {}  
            indicator_data[case_name][device_name][create_time]={
                'tp90': round(float(tp90),2),  
                'jank': round(float(jank),2),  
                'memory': round(float(peak_memory),2),  
                'perfeye': perfeye  
            }

    return indicator_data

# 读取或创建session文件
def read_or_create_session_file(filename='mysession.txt'):  
    try:  
        with open(filename, 'r') as file:  
            mysession = file.read()  
            headers['Cookie']=f"mysession={mysession[::-1]}"
            return mysession[::-1]
    except FileNotFoundError:  
        print("检测到您尚未登录！请登录！登录需要谷歌浏览器！")
        print("登录的浏览器界面可能会提示Chrome正受到自动测试软件的控制,这是正常的。")
        print("正在启动浏览器，请在稍后打开的浏览器界面登录...")
        mysession=login()
        print(mysession)
        if mysession and mysession!='':
            with open(filename, 'w') as file:  
                file.write(mysession[::-1])  
        return False
def download_image(index,url,dir):
    try:
        if not url or url=='':
            return 
        # 发送HTTP GET请求获取图片
        response = requests.get(url)
        response.raise_for_status()  # 如果请求失败，将引发HTTPError异常
        
        # 使用PIL打开图片（这里只是为了确保图片数据有效，实际上不需要保存为Image对象）
        image = Image.open(BytesIO(response.content))
        image.close()  # 关闭图像文件，因为我们不再需要它作为Image对象
        
        # 构造保存图片的文件名
        filename = os.path.join(dir, f'{index}.jpg')
        
        # 将图片数据写入文件
        with open(filename, 'wb') as f:
            f.write(response.content)
    except requests.RequestException as e:
        print(f'Error downloading {url}: {e}')
    except Exception as e:
        print(f'An unexpected error occurred while processing {url}: {e}')

def download_images(image_urls,dir):
    # 确保ImageList文件夹存在
    if not os.path.exists(dir):
        os.makedirs(dir)
    else:
        shutil.rmtree(dir)
        os.makedirs(dir)
    # 打开文件夹
    os.startfile(dir)
    # 创建一个ThreadPoolExecutor对象  
    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:  
        # 循环下载图片
        futures=[]
        for index, url in enumerate(image_urls):
            futures.append(executor.submit(download_image,index,url,dir))
            # 等待所有任务完成  
        concurrent.futures.wait(futures)  

def download_images_by_perfeye(perfeye,dir):
    url = f"https://perfeye.console.testplus.cn/api/show/task/{perfeye}"
    payload = {}
    response = requests.request("POST", url, headers=headers, data=payload)
    try:
        data = response.json()
        if data and "data" in data and "ResizeImageList" in data["data"]:
            imageList=data["data"]['ResizeImageList']
            download_images(imageList,f"案例截图\\{dir}")
        else:
            print("未找到预期数据！")
    except Exception :
        print(f"Error: {response.text}")
def update_max_case():
    global max_case
    response = requests.request("GET", total_url, headers=headers)
    data = response.json()
    data=getIndicator_diction(data)
    # 遍历到设备1层级
    for scene, devices in data.items():
        for device, perfeye_list in devices.items():
            # 将日期字典转换为列表，并按照tp90降序排序
            sorted_list = sorted(perfeye_list, key=lambda item: item['tp90'], reverse=True)
            devices[device] = sorted_list
    max_case={}
    choose_list=[]
    for scene, devices in data.items():
        max_case[scene]={}
        for device, date_list in devices.items():
            choose_list.append((scene,device))
            os.system("cls")
            print(f"【{scene}】-【{device}】({seven_days_ago}至{yesterday})")
            print(f"{date_list[0]['date']} 【{date_list[0]['tp90']}】【'https://perfeye.console.testplus.cn/case/{date_list[0]['perfeye']}/report?appKey=yycs'】")
            print(f"正在加载【{scene}-{device}】的案例截图...",end='')
            download_images_by_perfeye(date_list[0]['perfeye'],f'{scene}-{device}')
            print("加载完成")
            max_case[scene][device]=[]
            for i in range(len(date_list)):
                max_case[scene][device].append({"date":date_list[i]['date'],"tp90":date_list[i]['tp90'],"perfeye":date_list[i]['perfeye']})
    while True:
        try:
            os.system("cls")
            print("------------------------------------------------------------------")
            print("以下案例如果不正常请输入对应案例的序号，如果都正常则输入其他键退出。")
            for i,choose in enumerate(choose_list):
                print(f"{i+1}. {choose[0]}-{choose[1]}")
            print("------------------------------------------------------------------")
            choose=int(input("请输入:"))-1
            scene=choose_list[choose][0]
            device=choose_list[choose][1]
            max_case[scene][device].pop(0)
            if len(max_case[scene][device])==0:
                print("没有其余案例了！")
                break
            print(f"正在加载【{scene}-{device}】的案例截图...",end='')
            download_images_by_perfeye(max_case[scene][device][0]['perfeye'],f'{scene}-{device}')
            print("加载完成")
            continue
        except (TypeError,KeyError,ValueError):
            break
    for scene in max_case:
        for device in max_case[scene]:
            if len(max_case[scene][device]):
                max_case[scene][device]=max_case[scene][device][0]
            else:
                max_case[scene][device]={}
    # 将字典存储到文本文件
    with open('maxCasePC.txt', 'w', encoding='utf-8') as file:
        json.dump(max_case, file, ensure_ascii=False, indent=4)
def read_or_create_max_case_file():
    global max_case
    try:
        with open('maxCasePC.txt', 'r', encoding='utf-8') as file:
            max_case = json.load(file)
            for scene in max_case:
                for device in max_case[scene]:
                    # 将字符串转换为datetime对象
                    perfeye_date = datetime.strptime(max_case[scene][device]['date'], "%Y-%m-%d")
                    # 获取今天的日期
                    today = datetime.now()
                    # 计算两个日期之间的差值
                    date_difference = perfeye_date - today
                    if date_difference.days >= 7:
                        if input(f"【{scene}】记录中的最佳案例是{perfeye_date},距今以超过七天！是否重新获取最佳案例？(y/n):")!='n':
                            update_max_case()
                            return False
        return True
    except FileNotFoundError:
        update_max_case()
        return False

def disposeFPS(indicator):
    indicatorStr=""
    if indicator>=3 and rebotMode:
        indicatorStr+="<font color='green'>**"
    if indicator<=-3 and rebotMode:
        indicatorStr+="<font color='red'>**"
    if indicator>0:
        indicatorStr+='提升'
    else:
        indicatorStr+='下降'
    indicatorStr+=f'{round(abs(indicator),2)}'
    if abs(indicator)>=3 and rebotMode:
        indicatorStr+="**</font>"
    return indicatorStr
def disposeMemory(indicator):
    indicatorStr=""
    if indicator<=-100 and rebotMode:
        indicatorStr+="<font color='green'>**"
    if indicator>=100 and rebotMode:
        indicatorStr+="<font color='red'>**"
    if indicator>0:
        indicatorStr+='增加'
    else:
        indicatorStr+='减少'
    indicatorStr+=f'{round(abs(indicator),2)}'+'MB'
    if abs(indicator)>=100 and rebotMode:
        indicatorStr+="**</font>"
    return indicatorStr
def disposeJank(indicator):
    indicatorStr=""
    if indicator<=-100 and rebotMode:
        indicatorStr+="<font color='green'>**"
    if indicator>=100 and rebotMode:
        indicatorStr+="<font color='red'>**"
    if indicator>0:
        indicatorStr+='增加'
    else:
        indicatorStr+='减少'
    indicatorStr+=f'{round(abs(indicator),2)}'
    if abs(indicator)>=100 and rebotMode:
        indicatorStr+="**</font>"
    return indicatorStr
def printIndicatorData(data):
    global message
    global newPerfeyeUrlList
    global lowPerfeyeUrlList
    if not rebotMode:
        print(f"月影传说{today}场景性能情况汇总")
    for scene in scenes:
        if rebotMode:
            message+=f'---------------------【 {scene} 】---------------------<br>'
        else:
            print(f'---------------------【 {scene} 】---------------------')
        if scene not in data:
            if rebotMode:
                message+=f'------------------------------------未出数据<br>'
            else:
                print(f'------------------------------------未出数据')
            continue
        for i in range(len(deviceNames)):
            device_name=deviceNames[i]
            if deviceNames[i] not in data[scene]:
                if rebotMode:
                    message+=f'{device_name} : ------------------------------------未出数据<br>'
                else:
                    print(f'{device_name} : ------------------------------------未出数据')
                continue
            maxData=scene in max_case and device_name in max_case[scene] and max_case[scene][device_name]['date'] in data[scene][device_name]
            todayData=today in data[scene][device_name]
            if maxData:
                data1=data[scene][device_name][max_case[scene][device_name]['date']]
                max_day=max_case[scene][device_name]['date']
            if todayData:
                data2=data[scene][device_name][today]
            if maxData and todayData:
                tp90 = disposeFPS(data2['tp90'] - data1['tp90'])
                memory = disposeMemory(data2['memory'] - data1['memory'])
                jank = disposeJank(data2['jank'] - data1['jank'])
                lowPerfeyeUrlList.append(f'https://perfeye.console.testplus.cn/case/{data1['perfeye']}/report?appKey=yycs')
                newPerfeyeUrlList.append(f'https://perfeye.console.testplus.cn/case/{data2['perfeye']}/report?appKey=yycs')
                if rebotMode:
                    message+=f' [{device_name}](https://perfeye.console.testplus.cn/case/{data2['perfeye']}/report?appKey=yycs):'
                    message+=f' {data2['tp90']}({tp90}) ,  {data2['memory']}({memory}) ,  {data2['jank']}({jank})'
                    message+=f',[对比案例](https://perfeye.console.testplus.cn/case/{data1['perfeye']}/report?appKey=yycs)<br>'
                else:
                    print(f'{device_name} : {data2['tp90']}({tp90}) ,  {data2['memory']}({memory}) ,  {data2['jank']}({jank})')
                    # print(f'https://perfeye.console.testplus.cn/case/{data1['perfeye']}/report?appKey=yycs')
                    # print(f'https://perfeye.console.testplus.cn/case/{data2['perfeye']}/report?appKey=yycs')
            elif todayData:
                newPerfeyeUrlList.append(f'https://perfeye.console.testplus.cn/case/{data2['perfeye']}/report?appKey=yycs')
                if rebotMode:
                    message+=f' [{device_name}](https://perfeye.console.testplus.cn/case/{data2['perfeye']}/report?appKey=yycs):'
                    message+=f' {data2['tp90']},  {data2['memory']},  {data2['jank']}-----------<font color="grey">**最优案例无数据**</font><br>'
                else:
                    print(f'{device_name} : {data2['tp90']},  {data2['memory']},  {data2['jank']}\t\t最优案例无数据')
            elif maxData:
                lowPerfeyeUrlList.append(f'https://perfeye.console.testplus.cn/case/{data1['perfeye']}/report?appKey=yycs')
                if rebotMode:
                    message+=f' [{device_name}({max_day})](https://perfeye.console.testplus.cn/case/{data1['perfeye']}/report?appKey=yycs):'
                    message+=f' {data1['tp90']},  {data1['memory']},  {data1['jank']}<font color="grey">**【{today}】未出数据**</font><br>'
                else:
                    print(f'{device_name} : {data1['tp90']},  {data1['memory']},  {data1['jank']}\t\t【{today}】未出数据')
    if not rebotMode:
        for i in range(len(lowPerfeyeUrlList)):
            print(f'{lowPerfeyeUrlList[i]}')
        # for i in range(len(newPerfeyeUrlList)):
            print(f'{newPerfeyeUrlList[i]}')


def compare_today_and_max_perfeye():
    global rebot_url,message
    test=input("是不是在测试？(y/n)")
    if test!='n':
        rebot_url="https://xz.wps.cn/api/v1/webhook/send?key=f4b5d2acf9f0150a3e507e8797369018"
    else:
        rebot_url = "https://xz.wps.cn/api/v1/webhook/send?key=7b5145844387651189f3d387671b5a28"
    message=default_message
    url = f"https://automation-api.testplus.cn/api/pipeline/304/performance/trend?pipelineId=304&startTime={seven_days_ago}+00:00:00&endTime={today}+23:59:59&projectId=yycs"
    response = requests.request("GET", url, headers=headers)
    data = response.json() 
    data=getIndicator_diction(data,'dateDict')
    if data:
        printIndicatorData(data)
        if rebotMode:
            rebotSendMessage(rebot_url,message)
def init():
    mysession = read_or_create_session_file()
    while not mysession:
        mysession = read_or_create_session_file()
    max_case_stauts=read_or_create_max_case_file()
    while not max_case_stauts:
        max_case_stauts = read_or_create_max_case_file()
    compare_today_and_max_perfeye()
if __name__ == "__main__":
    init()

